Arc<T>
from Rustのポインタ型
Atomic Reference Counting
複数のスレッド間で安全に参照カウントを管理するためのsmart pointer
スレッド間通信できる
std::sync
docs
定義
code:rs
pub struct Arc<T, A = Global>
where
A: Allocator,
T: ?Sized,
{ /* private fields */ }
/mrsekut-book-4065301955/085 (3.5 借用と排他制御の類似性)
#wip
https://qiita.com/qnighy/items/4bbbb20e71cf4ae527b9
Arc::newで値を生成すると、以下がヒープに確保される
Arc 内部で保持する値
その参照カウント
参照カウント
Arcをcloneすると1増える
そのArcのlifetimeが終了すると1減る
参照カウントが0になった場合に、ヒープに確保した領域を開放する
code:rust
use std::sync::Arc;
let a = Arc::new(vec!1, 2, 3); // 参照カウント: 1
let b = a.clone(); // 参照カウント: 2
let c = a.clone(); // 参照カウント: 3
Arcのcloneは、一般的なcloneと異なり、
値のコピーはされず、参照カウントが増えるだけ
同じ名前で良いの?紛らわしくない?mrsekut.icon
ArcとRc<T>の違い
Arcは複数のスレッド間でデータ共有できる
スレッド間通信できる
Rcは1スレッド内でのみデータ共有できる
↑これのことをスレッドセーフと呼ぶの?mrsekut.icon
スレッドセーフとは、複数のスレッドが同時にアクセスしても問題がない状態を指します。gpt-4.icon
なるほどmrsekut.icon
Arcのcloneの方がRcよりオーバーヘッドが大きい
GPT-4.icon
1. Arcとは?
Rc<T>と同様に、参照カウントを用いて所有権を共有する仕組みを持つ。
異なるスレッド間で使用できるように、アトミック操作によって参照カウントが増減する。
スレッド間でデータを共有する必要がある場合に使う。
2. 使い方
code:rust
use std::sync::Arc;
use std::thread;
fn main() {
let data = Arc::new(vec!1, 2, 3);
let handles: Vec<_> = (0..3).map(|_| {
let data = Arc::clone(&data);
thread::spawn(move || {
println!("{:?}", data);
})
}).collect();
for handle in handles {
handle.join().unwrap();
}
}
ポイント:
1. Arc::new(vec![1, 2, 3]) で Arc<T> を作成
2. Arc::clone(&data) を使って クローンを作成(参照カウントが増加)
3. thread::spawn で複数スレッドに安全に渡せる